`timescale 1ns / 1ps

module SPI4AD9106(
//	inputs
	input				clk,
	input				trig,
//	input wire[31:0] 	spi_data,
	input 				spi_cpol,
	input				spi_cpha,
	input				ps_A0,
	input				ps_A1,

//	outputs:
	output				A0,
	output				A1,
	output				sclk,
	output				mosi,
	output				status   // 为1时表示行转移结束
	);

//	assign A0 = ps_A0;
//	assign A1 = ps_A1;

    reg A0_r, A1_r;
	assign A0 = A0_r;
    assign A1 = A1_r;

//  模拟一次RST脉冲，用于初始化SPI_BASE
	reg[7:0]  reset_cnt;
	reg       reset_r;
	reg		  en_r;

//	finished:连接SPI_BASE的finished
	wire finished;
	parameter clk_div = 5; // 如果输入时钟为50M，那么在spi_base内部分频的时钟为50M/5/2=5M

//	状态机：
	reg[3:0] state;			// defailt: SPI_IDLE
	parameter SPI_IDLE	= 4'd0;
	parameter SPI_RESET	= 4'd1;
	parameter SPI_SEND1	= 4'd2;
	parameter SPI_SEND2	= 4'd3;
	parameter SPI_SEND3	= 4'd4;
	parameter SPI_SEND4	= 4'd5;
	parameter SPI_SEND5	= 4'd6;
	parameter SPI_SEND6	= 4'd7;
	parameter SPI_SEND7	= 4'd8;
	parameter SPI_SEND8	= 4'd9;
	parameter SPI_FINISHED	= 4'd10;
	
	reg[31:0] spi_data_r; // = {16'h0001,16'h01cf};
	wire[31:0] spi_data = spi_data_r;
	reg[3:0] flag = 4'd0;
	reg[15:0] flag_cnt = 16'd0;
	localparam cnt_offset  = 16'd100;
	localparam cnt1    = 16'd500 - cnt_offset;
	localparam cnt2    = 16'd1000 - cnt_offset;
	localparam cnt3    = 16'd1500 - cnt_offset;
	localparam cnt4    = 16'd2000 - cnt_offset;
	localparam cnt5    = 16'd2500 - cnt_offset;
	localparam cnt6    = 16'd3000 - cnt_offset;
	localparam cnt7    = 16'd3500 - cnt_offset;
	localparam cnt8    = 16'd4000 - cnt_offset;

//	localparam cnt_offset  = 16'd40;
//	localparam cnt1    = 16'd50 - cnt_offset;
//	localparam cnt2    = 16'd100 - cnt_offset;
//	localparam cnt3    = 16'd150 - cnt_offset;
//	localparam cnt4    = 16'd200 - cnt_offset;
//	localparam cnt5    = 16'd250 - cnt_offset;
//	localparam cnt6    = 16'd300 - cnt_offset;
//	localparam cnt7    = 16'd350 - cnt_offset;
//	localparam cnt8    = 16'd400 - cnt_offset;

//	SPI_BASE 例化
	SPI_BASE#(
			.DATAWIDTH(32),
            .CLKDIV(clk_div)
		) spi (
			.clk(clk),
			.rst(reset_r),
			.din(spi_data),
			.en(en_r),
			.CPOL(spi_cpol),
			.CPHA(spi_cpha),
			.sclk(sclk),
			.dout(mosi),
			.finished(finished)
		);

//	status 表示当前32bit是否传输完成
	reg status_r = 1'b0;
	assign status = status_r;

	always @(posedge clk or posedge trig) begin
		if ( trig )
			flag_cnt <= 32'd0;
		else
			flag_cnt <= flag_cnt + 32'd1;
	end

	always @(posedge clk or posedge trig) begin
		if ( trig ) begin
			// reset
			state			<= SPI_IDLE;
			en_r			<= 0;
			reset_r			<= 0;
			reset_cnt		<= 8'b0;
			status_r		<= 1'b0;
			spi_data_r  	<= {16'h0001,16'h01c9};
		
		//  CS拉高
			A0_r            <= ~ps_A0;
			A1_r            <= ~ps_A1;
		end
		else begin
			case(state)
				SPI_IDLE:
				begin
					if( status_r == 1'b0 ) begin
						en_r		<= 0;
	                    reset_r		<= 0;
	                    reset_cnt	<= 8'b0;
						status_r	<= 1'b0;
//						spi_data    <= {16'h0001,16'h01c9};
						
						A0_r        <= ~ps_A0;
						A1_r        <= ~ps_A1;
						
						if( flag_cnt == cnt1 ) begin
						    state	<= SPI_RESET;
						    flag    <= 4'd1;
						end
						else if( flag_cnt == cnt2 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd2;
                        end
						else if( flag_cnt == cnt3 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd3;
                        end
						else if( flag_cnt == cnt4 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd4;
                        end
						else if( flag_cnt == cnt5 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd5;
                        end
						else if( flag_cnt == cnt6 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd6;
                        end
						else if( flag_cnt == cnt7 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd7;
                        end
						else if( flag_cnt == cnt8 ) begin
                            state    <= SPI_RESET;
                            flag    <= 4'd8;
                        end
                        else
                            state   <= SPI_IDLE;
					end
				end

				SPI_RESET:  // 模拟SPI复位信号
				begin
					if( reset_cnt <= 4 ) begin
						reset_r		<= 0;
						reset_cnt	<= reset_cnt + 1;
					end
					else if( reset_cnt <= 6 ) begin
						reset_r		<= 1;
						reset_cnt	<= reset_cnt + 1;
                        
                        // CS拉低
                        A0_r        <= ps_A0;
                        A1_r        <= ps_A1;
					end
					else if( reset_cnt >= 7 ) begin
						reset_r		<= 0;
						en_r		<= 1;
						
						// 根据计数器判断该发送哪个数据？
						if( flag == 1 ) begin
						    state	<= SPI_SEND1;
						    spi_data_r  <= {16'h0001,16'h01c8};
                        end
						else if( flag == 2 ) begin
						    state <= SPI_SEND2;
						    spi_data_r  <= {16'h0001,16'h01cc};
                        end
						else if( flag == 3 ) begin
                            state <= SPI_SEND3;
                            spi_data_r  <= {16'h0001,16'h01c4};
                        end
                        else if( flag == 4 ) begin
                            state <= SPI_SEND4;
                            spi_data_r  <= {16'h0001,16'h01c6};
                        end
                        else if( flag == 5 ) begin
                            state <= SPI_SEND5;
                            spi_data_r  <= {16'h0001,16'h01c2};
                        end
                        else if( flag == 6 ) begin
                            state <= SPI_SEND6;
                            spi_data_r  <= {16'h0001,16'h01c3};
                        end
                        else if( flag == 7 ) begin
                            state <= SPI_SEND7;
                            spi_data_r  <= {16'h0001,16'h01c1};
                        end
                        else if( flag == 8 ) begin
                            state <= SPI_SEND8;
                            spi_data_r  <= {16'h0001,16'h01c9};
                        end
					end
				end

				SPI_SEND1:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND2:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND3:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND4:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND5:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND6:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND7:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_IDLE;
						en_r	<= 0;
					end
				end

				SPI_SEND8:
				begin
					if( finished == 1'b1 ) begin
						state	<= SPI_FINISHED;
						en_r	<= 0;
					end
				end

				SPI_FINISHED:
				begin
					state		<= SPI_IDLE;
					status_r	<= 1'b1;
				end

				default:
					state 	<= SPI_IDLE;
			endcase
		end
	end
endmodule
